#!/usr/bin/env python
# -*- coding: utf8 -*-
# title       :
# description :
# author      :'ShenMeng'


from PySide import QtGui, QtCore
import os
import socket
import getpass
# import _winreg
import ui_style
from .verbatchmanager import BatchManager
from functools import partial
import subprocess
import resources_rc
import yaml
import uuid


class MyThread(QtCore.QThread):
    task_data = []
    substate = False
    state = False
    def __init__(self,item_model, parent=None):
        super(MyThread, self).__init__(parent=parent)
        self.mutex = QtCore.QMutex()
        self.item_model = item_model
        
    def run(self):
        with QtCore.QMutexLocker(self.mutex):
            self.state = True
        while True:
            if self.task_data:
                cmd = self.task_data[0].get('cmd')
                item = self.task_data[0].get('item')
                itemModel = self.task_data[0].get('itemModel')

                row = itemModel.indexFromItem(item).row()

                manager = self.task_data[0].get('manager')
                file_name = self.task_data[0].get('file')
                task_state = 'doing'
                image = ":icons/stop_icon.png"
                itemModel.setItem(row, 0, QtGui.QStandardItem(QtGui.QIcon(image), file_name))
                itemModel.setItem(row, 4, QtGui.QStandardItem(task_state))
                # 
                # task_state = 'Ok'
                # """
                if self.do_job(cmd):
                    task_state = 'Error'
                else:
                    task_state = 'Ok'
                # """
                #
                #self.emit(QtCore.SIGNAL("updateinfo"), "hello")
                if manager.taskOkData and file_name in manager.taskOkData:
                    image = ":icons/success.png"
                elif manager.taskErrorData and file_name in manager.taskErrorData:
                    image = ":icons/failure.png"
                else:
                    image = ":icons/failure.png"
                
                itemModel.setItem(row, 0, QtGui.QStandardItem(QtGui.QIcon(image), file_name))
                itemModel.setItem(row, 4, QtGui.QStandardItem(task_state))

                self.task_data.remove(self.task_data[0])
                #self.substate = False
 
    def subprocess_popen(self, *args, **kwargs):
        start_info = subprocess.STARTUPINFO()
        start_info.dwFlags = subprocess.CREATE_NEW_CONSOLE | subprocess.STARTF_USESHOWWINDOW
        start_info.wShowWindow = subprocess.SW_HIDE
        kwargs['startupinfo'] = start_info
        retcode = subprocess.Popen(*args, **kwargs)
        return retcode
        
    def do_job(self, cmd):
        print '>'*100
        print cmd
        p = self.subprocess_popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=False)
        try:
            curline = p.stdout.readline()
            while(curline !=''):
                curline = p.stdout.readline()
                print curline
                #self.emit(QtCore.SIGNAL("updateinfo"), curline)
                
                #if self.substate:
                #    if p.stdin:
                #        p.stdin.close()
                #    if p.stdout:
                #        p.stdout.close()
                #    if p.stderr:
                #        p.stderr.close()
                #    try:
                #        p.kill()
                #    except:pass
                #    return
        except Exception, e:
            print str(e)
            return
        finally:
            p.wait()
            if p.stdin:
                p.stdin.close()
            if p.stdout:
                p.stdout.close()
            if p.stderr:
                p.stderr.close()
            try:
                p.kill()
            except:pass

class BatchManagerUi(QtGui.QDialog):
    
    def __init__(self, config=None, parent=None):
        super(BatchManagerUi, self).__init__(parent=parent)
        self.setStyleSheet(ui_style.STANDARD_STYLE)
        self._manager_data = []
        self._title = 'batch manager'
        self.setWindowTitle(self._title)
        # self._config = 'C:/Users/shenmeng/packages/batchmanager/0.0.2/batchmanager/config/deformationcar.yml'
        self._config = config
  
    def _init_data(self):
        config_file = self.get_config_file()
        if config_file:
            try:
                with open(config_file) as f:
                    self._data = yaml.load(f)
            except:
                pass
            else:
                return True
        message_box = QtGui.QMessageBox().information(self, u'提示', u'配置文件错误！请联系TD解决！')
            
    def get_config_file(self):
        if not self._config:
            config_path = os.getenv("BATCH_MANAGER_CONFIG")
            if not config_path:
                return
            if os.path.isfile(config_path):
                return config_path
            return
            
        if os.path.isfile(self._config):
            return self._config
        else:
            config_path = os.getenv("BATCH_MANAGER_CONFIG")
            if config_path:
                if os.path.isfile(config_path):
                    config_file = config_path
                elif os.path.isdir(config_path):
                    config_file = os.path.join(config_path, self._config)
            else:
                config_file = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'config', self._config)
            if os.path.isfile(config_file):
                return config_file.replace('\\', '/')
                
    def _ui(self):
        class SubmitBtn(QtGui.QPushButton):
            def __init__(self, text='',  parent=None):
                super(SubmitBtn, self).__init__( parent=parent)
                self._text = text
                self.setCheckable(0)
                main_layout = QtGui.QHBoxLayout(self)
                self.customText = QtGui.QLabel(text)
                self.customText.setStyleSheet("background:rgba(0,0,0,0)")
                main_layout.addItem(QtGui.QSpacerItem(0,0, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding))
                main_layout.addWidget(self.customText)
                main_layout.addItem(QtGui.QSpacerItem(0,0, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding))
                main_layout.setContentsMargins(0,0,0,0)
                main_layout.setSpacing(0)
                self.customText.setAlignment(QtCore.Qt.AlignCenter)
                self.updateCustomText(0)
                self.customText.mouseReleaseEvent = self.customClicked
                
            def customClicked(self, event):
                self.mouseReleaseEvent(event)
                
            def updateCustomText(self, text):
                if self._text:
                    if int(text) == 0:
                        color = 'red'
                    else:
                        color = 'rgb(0,255,0)'
                    self.customText.setText('<html><head/><body>%s ( <span style="color:%s;">%s</span> )</body></html>' %(self._text, color, text))
                
        # >> create navigation btn
        navigation_submit_btn = QtGui.QPushButton('Submit')
        navigation_submit_btn.setCheckable(1)
        navigation_submit_btn.setChecked(1)
        navigation_task_btn = QtGui.QPushButton('Task')
        navigation_task_btn.setCheckable(1)
        navigation_info_btn = QtGui.QPushButton('Info')
        navigation_info_btn.setCheckable(1)
        self.navigation_btn_group = QtGui.QButtonGroup()
        self.navigation_btn_group.addButton(navigation_submit_btn, 0)
        self.navigation_btn_group.addButton(navigation_task_btn, 1)
        self.navigation_btn_group.addButton(navigation_info_btn, 2)
        navigation_btn_layout = QtGui.QHBoxLayout()
        navigation_btn_layout.addWidget(navigation_submit_btn)
        navigation_btn_layout.addWidget(navigation_task_btn)
        navigation_btn_layout.addWidget(navigation_info_btn)
        # connect
        self.navigation_btn_group.buttonClicked.connect(self.on_navigation_btn_group_clicked)
        
        
        # >> create pages
        self.stacked_widget = QtGui.QStackedWidget()
        local_task_page = QtGui.QWidget()
        server_task_page = QtGui.QWidget()
        #info_page = QtGui.QWidget()
        self.stacked_widget.addWidget(local_task_page)
        self.stacked_widget.addWidget(server_task_page)
        #self.stacked_widget.addWidget(info_page)
        

        # >> submit page
        _root_label = QtGui.QLabel('Path : ')
        self.root_line = QtGui.QLineEdit()
        self.root_line.setMinimumHeight(22)
        self.root_btn = QtGui.QPushButton('...')
        self.root_btn.setMaximumSize(40, 22)
        self.root_btn.setMinimumSize(40, 22)
        root_layout = QtGui.QHBoxLayout()
        root_layout.setSpacing(0)
        root_layout.setContentsMargins(4, 0, 0,0)
        root_layout.addWidget(_root_label)
        root_layout.addWidget(self.root_line)
        root_layout.addWidget(self.root_btn)
        
        self.submit_data_frame = QtGui.QFrame()
        self.submit_data_frame.setEnabled(0)

        self.sel_num_line = QtGui.QLineEdit()
        self.sel_num_line.setMaximumSize(35, 18)
        self.sel_num_slider = QtGui.QSlider()
        self.sel_num_slider.setOrientation(QtCore.Qt.Horizontal)
        self.sel_num_slider.setMinimumSize(150, 20)
        self.sel_num_slider.setMaximumSize(150, 20)
        self.sel_num_slider.setEnabled(0)
        check_box_layout = QtGui.QHBoxLayout()
        self.submit_data_layout = QtGui.QVBoxLayout(self.submit_data_frame)
        ####
        self._box = {}
        for name in self._data.keys():
            subData = self._data[name].get('sub')
            type_label = QtGui.QLabel('{} : '.format(name.capitalize()))
            grp_layout = QtGui.QHBoxLayout()
            grp_layout.setContentsMargins(4, 0, 0,0)
            grp_layout.setSpacing(6)
            grp_layout.addWidget(type_label)
            ###
            box = QtGui.QCheckBox('all')
            box_uuid = uuid.uuid4().hex
            check_box_layout.addWidget(box)
            box.stateChanged.connect(partial(self.on_batch_type_btn_clicked, box_uuid))
            self._box[box_uuid] = dict(box=box, type=str(name), sub='all')
            # self.submit_data_layout.addLayout(check_box_layout)
            grp_layout.addWidget(box)
            ###
            if subData:
                sub_keys = subData.keys()
                sub_keys.sort()
                for sub_type in sub_keys:
                    box = QtGui.QCheckBox(sub_type)
                    box_uuid = uuid.uuid4().hex
                    box.stateChanged.connect(partial(self.on_batch_type_btn_clicked, box_uuid))
                    self._box[box_uuid] = dict(box=box, type=str(name), sub=str(sub_type))
                    grp_layout.addWidget(box)
                grp_layout.addItem(QtGui.QSpacerItem(0,0,QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding))
            self.submit_data_layout.addLayout(grp_layout)
            #    

        submit_set_layout = QtGui.QHBoxLayout()
        submit_set_layout.setContentsMargins(4, 0, 0,0)
        #
        submit_set_layout.addWidget(self.sel_num_line)
        submit_set_layout.addItem(QtGui.QSpacerItem(0,0,QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding))
        submit_set_layout.addWidget(self.sel_num_slider)
        self.submit_btn = SubmitBtn('Submit')#QtGui.QPushButton('Submit ( 0 )')
        
        self.submit_btn.setEnabled(0)
        self.file_list_widget = QtGui.QListWidget()
        self.file_list_widget.setFocusPolicy(QtCore.Qt.NoFocus)
        self.file_list_widget.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
        
        
        #self.submit_data_layout.addLayout(check_box_layout)
        self.submit_data_layout.addLayout(submit_set_layout)
        self.submit_data_layout.addWidget(self.file_list_widget)
        self.submit_data_layout.addWidget(self.submit_btn)
        self.submit_data_layout.setStretch(2,10)
        self.submit_data_layout.setContentsMargins(0,0,0,0)
        
        self.submit_layout = QtGui.QVBoxLayout()#submit_page)
        self.submit_layout.addLayout(root_layout)
        self.submit_layout.addWidget(self.submit_data_frame)
        self.submit_layout.setStretch(1,10)
        self.submit_layout.setContentsMargins(0,0,0,0)
        # connect
        self.root_btn.clicked.connect(self.on_root_btn_clicked)
        self.sel_num_slider.valueChanged.connect(self.on_sel_num_slider_value_changed)
        self.file_list_widget.itemSelectionChanged.connect(self.on_file_list_widget_selection_changed)
        self.submit_btn.clicked.connect(self.on_submit_btn_clicked)
        
        # >> server task
        server_task_page_layout = QtGui.QVBoxLayout(server_task_page)#task_page)
        server_task_page_layout.setContentsMargins(0,0,0,0)
        self.server_task_view = QtGui.QTableView()
        self.server_task_view.setFocusPolicy(QtCore.Qt.NoFocus)
        self.server_task_view.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
        self.server_task_view.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
        self.server_task_view.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
        self.server_task_item_model = QtGui.QStandardItemModel()
        self.server_task_item_model.setHorizontalHeaderItem(0, QtGui.QStandardItem(u"文件名"))
        self.server_task_item_model.setHorizontalHeaderItem(1, QtGui.QStandardItem(u"类型"))
        self.server_task_item_model.setHorizontalHeaderItem(2, QtGui.QStandardItem(u"任务分组"))
        self.server_task_item_model.setHorizontalHeaderItem(3, QtGui.QStandardItem(u"所有者"))
        self.server_task_item_model.setHorizontalHeaderItem(4, QtGui.QStandardItem(u"状态"))
        self.server_task_view.setModel(self.server_task_item_model)
        server_task_page_layout.addWidget(self.server_task_view)
        # 
        # self.server_task_view.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        # self.server_task_view.customContextMenuRequested.connect(partial(self.create_context_menu, self.server_task_view))
        
        # >> local task
        local_task_page_layout = QtGui.QVBoxLayout(local_task_page)#task_page)
        local_task_page_layout.setContentsMargins(0,0,0,0)
        
        self.task_view = QtGui.QTableView()
        self.task_view.setFocusPolicy(QtCore.Qt.NoFocus)
        # headerItem
        self.task_item_model = QtGui.QStandardItemModel()
        self.task_item_model.setHorizontalHeaderItem(0, QtGui.QStandardItem(u"文件名"))
        self.task_item_model.setHorizontalHeaderItem(1, QtGui.QStandardItem(u"类型"))
        self.task_item_model.setHorizontalHeaderItem(2, QtGui.QStandardItem(u"任务分组"))
        self.task_item_model.setHorizontalHeaderItem(3, QtGui.QStandardItem(u"所有者"))
        self.task_item_model.setHorizontalHeaderItem(4, QtGui.QStandardItem(u"状态"))
        self.task_view.setModel(self.task_item_model)
        # style
        # 
        self.task_view.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
        self.task_view.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
        self.task_view.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
        self.task_view.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.task_view.customContextMenuRequested.connect(partial(self.create_context_menu, self.task_view))
        
        
        self.task_btn = QtGui.QPushButton()
        local_task_page_layout.addWidget(self.task_view)
        self.myThread = MyThread(item_model=self.task_item_model)
        #self.connect(self.myThread, QtCore.SIGNAL('updateinfo'), self.updateinfo)
        
        # task check
        self.task_radio_btn_grp = QtGui.QButtonGroup()
        local_task_btn = QtGui.QCheckBox("local")
        local_task_btn.setChecked(1)
        server_task_btn = QtGui.QCheckBox("server")
        self.task_radio_btn_grp.addButton(local_task_btn,0)
        self.task_radio_btn_grp.addButton(server_task_btn,1)
        self.server_refresh_btn = QtGui.QToolButton()
        self.server_refresh_btn.setIcon(QtGui.QIcon(":icons/refresh.png"))
        self.server_refresh_btn.setEnabled(0)
        task_btn_layout = QtGui.QHBoxLayout()
        task_btn_layout.addItem(QtGui.QSpacerItem(0,0, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding))
        task_btn_layout.addWidget(local_task_btn)
        task_btn_layout.addWidget(server_task_btn)
        task_btn_layout.addWidget(self.server_refresh_btn)
        self.task_radio_btn_grp.buttonClicked.connect(self.on_task_btn_clicked)
        task_btn_layout.setContentsMargins(4,4,4,4)
        task_btn_layout.setSpacing(10)
        self.server_refresh_btn.clicked.connect(self.on_server_refersh_btn_clicked)
        
        #
        task_layout = QtGui.QVBoxLayout()
        task_layout.setContentsMargins(0,0,0,0)
        task_layout.addWidget(self.stacked_widget)
        task_layout.addLayout(task_btn_layout)
        task_layout.setStretch(0, 10)
        
        # main frame
        self.main_frame = QtGui.QFrame()
        self.main_frame_layout = QtGui.QHBoxLayout(self.main_frame)
        self.main_frame_layout.addLayout(self.submit_layout)
        self.main_frame_layout.addLayout(task_layout)
        self.main_frame_layout.setStretch(1,10)
        self.main_frame_layout.setContentsMargins(0,0,0,0)
        # >> main layout
        self.main_layout = QtGui.QVBoxLayout(self)
        self.main_layout.setSpacing(0)
        self.main_layout.setContentsMargins(0,0,0,0)
        #self.main_layout.addLayout(navigation_btn_layout)
        #self.main_layout.addWidget(self.stacked_widget)
        self.main_layout.addWidget(self.main_frame)
        self._set_logo()
        
    def create_context_menu(self, view, *args):
        itemModel = view.model()
        selectionModel = view.selectionModel()
        if not itemModel.rowCount():
            return
        if not selectionModel.hasSelection():
            return
        
        contextMenu = QtGui.QMenu(self)
        redoAction = contextMenu.addAction(u'重新开始')
        delAction = contextMenu.addAction(u'删除任务')
        redoAction.triggered.connect(partial(self.on_redo_action_triggered, contextMenu, view))
        delAction.triggered.connect(partial(self.on_del_action_triggered, contextMenu, view))
        contextMenu.exec_(QtGui.QCursor.pos())
        contextMenu.show()
        
    def on_del_action_triggered(self, menu, view, *args):
        selectionModel = view.selectionModel()
        itemModel = view.model()
        result = {}
        row_list = [index.row() for index in selectionModel.selectedRows()]
        row_list.sort()
        row_list.reverse()
        for row in row_list:
            file_name = itemModel.item(row).text()
            type_data = dict(type=str(itemModel.item(row, 1).text()), sub=str(itemModel.item(row, 2).text()))
            result.setdefault(type_data['type'], {}).setdefault(type_data['sub'], []).append(file_name)
        if result:
            root_path = self.root_line.text()
            for batch_type, sub_data in result.iteritems():
                for sub_type, file_list in sub_data.iteritems():
                    manager = BatchManager(batch_type, root_path, sub_type)
                    assignData = manager.assignData
                    okData = manager.okData
                    errorData = manager.errorData
                    taskAssignData = manager.taskAssignData
                    taskOkData = manager.taskOkData
                    taskErrorData = manager.taskErrorData
                    for fileName in file_list:
                        for _data in [assignData, okData, errorData, taskAssignData, taskOkData, taskErrorData]:
                            if _data:
                                if fileName in _data:
                                    if isinstance(_data, list):
                                        _data.remove(fileName)
                                    else:
                                        _data.pop(fileName)
                    # TODO lock 
                    if manager.isAssignDataLock or manager.isOkDataLock or manager.isErrorDataLock:
                        self.close_menu(menu)
                        message_box = QtGui.QMessageBox().information(self, u'提示', u'数据被其他用户锁定，请稍后再试！')
                        return
                    manager.setAssignDataLock(1)
                    manager.setOkDataLock(1)
                    manager.setErrorDataLock(1)
                    manager.updateTaskAssignData(taskAssignData, 'w')
                    manager.updateTaskOkData(taskOkData, 'w')
                    manager.updateTaskErrorData(taskErrorData, 'w')
                    manager.updateAssignData(assignData, 'w')
                    manager.updateOkData(okData, 'w')
                    manager.updateErrorData(errorData, 'w')
                    manager.setAssignDataLock(0)
                    manager.setOkDataLock(0)
                    manager.setErrorDataLock(0)

            for row in row_list:
                file_name = itemModel.item(row).text()
                type_data = dict(type=str(itemModel.item(row, 1).text()), sub=str(itemModel.item(row, 2).text()))
                # batch_type = itemModel.item(row, 1).text()
                for cmdData in self.myThread.task_data:
                    if cmdData['type_data'] == type_data and cmdData['file'] == file_name:
                        self.myThread.task_data.remove(cmdData)
                        itemModel.takeRow(row)
                        break
                itemModel.takeRow(row)
                
        self.close_menu(menu)
        
        
    def on_redo_action_triggered(self, menu, view, *args):
        selectionModel = view.selectionModel()
        itemModel = view.model()
        result = {}
        root_path = self.root_line.text()
        for index in selectionModel.selectedRows():
            item = itemModel.item(index.row())
            type_data = dict(type=str(itemModel.item(index.row(), 1).text()), 
                             sub=str(itemModel.item(index.row(), 2).text()))
            # result.setdefault(type_item.text(), {})[item.text()] = dict(row=index.row(), sub=type_sub)
            result.setdefault(type_data['type'], {}).setdefault(type_data['sub'], {})[item.text()] = index.row()
            #result.append(item.text())

        for batch_type, sub_data in result.iteritems():
            for sub_type, data in sub_data.iteritems():
                manager = BatchManager(batch_type, root_path, sub_type)
                # error
                taskErrorData = manager.taskErrorData
                errorData = manager.errorData
                # ok
                taskOkData = manager.taskOkData
                okData = manager.okData
                for fileName in data:
                    for _data in [taskErrorData, errorData, taskOkData, okData]:
                        if _data:
                            if fileName in _data.keys():
                                _data.pop(fileName)

                    #manager.update
                if manager.isOkDataLock or manager.isErrorDataLock:
                    self.close_menu(menu)
                    message_box = QtGui.QMessageBox().information(self, u'提示', u'数据被其他用户锁定，请稍后再试！')
                    return
                manager.setErrorDataLock(1)
                manager.setOkDataLock(1)
                manager.updateTaskErrorData(taskErrorData, 'w')
                manager.updateErrorData(errorData, 'w')
                manager.updateTaskOkData(taskOkData, 'w')
                manager.updateOkData(okData, 'w')
                manager.setErrorDataLock(0)
                manager.setOkDataLock(0)
                type_data = dict(type=str(batch_type), sub=str(sub_type))
                for fileName, row in data.iteritems():
                    itemModel.setItem(row, 0, QtGui.QStandardItem(QtGui.QIcon(":icons/clock.png"),item.text()))
                    #self.task_item_model.setItem(row, 1, QtGui.QStandardItem(batch_type))
                    itemModel.setItem(row, 4, QtGui.QStandardItem('Waiting'))
                    item = itemModel.item(index.row())
                    cmd_str = self.get_cmd(manager, type_data, fileName)
                    self.myThread.task_data.append({'cmd':cmd_str, "itemModel":itemModel,'item':item, 'manager':manager, 'file':fileName, 'type_data': type_data })
        self.close_menu(menu)
        
    def close_menu(self, menu):
        try:
            menu.close()
            menu.deleteLater()
        except:pass
        
        
    def _set_logo(self):
        from framewidget import LogoFrame
        logo_frame = LogoFrame(name=self._title)
        logo_frame.set_bottom_border(1)
        self.main_layout.insertWidget(0, logo_frame)
        
    def on_task_btn_clicked(self, *args):
        index = self.task_radio_btn_grp.checkedId()
        self.stacked_widget.setCurrentIndex(index)
        self.server_refresh_btn.setEnabled(index)
        
    def on_batch_type_btn_clicked(self, name, *args):
        self.file_list_widget.clear()
        box = self._box[name]['box']
        if box.isChecked():
            for n in self._box:
                if n != name:
                    box = self._box[n]['box']
                    box.setCheckState(QtCore.Qt.Unchecked)
                    
            type_data = self.get_batch_type()
            if type_data:
                root_path = self.root_line.text()
                self.manager = BatchManager(type_data['type'], root_path, type_data['sub'])
                if self.manager.isAssignDataLock:
                    # TODO
                    box.setCheckState(QtCore.Qt.Unchecked)
                    message_box = QtGui.QMessageBox().information(self, u'提示', u'其他用户(ID:%s)正在提交中，数据被锁定，请稍后再试！' % self.manager.assignUser)
                else:
                    self.add_file_list_widget_item()
            else:
                self.manager = None
                self.submit_btn.setEnabled(0)
                self.sel_num_line.setEnabled(0)
                self.sel_num_slider.setEnabled(0)
            
    def _refresh(self):
        for name in self._box:
            box = self._box[name]['box']
            box.setCheckState(QtCore.Qt.Unchecked)
            
    def get_batch_type(self):
        for name in self._box:
            box = self._box[name]['box']
            if box.isChecked():
                return dict(type=str(self._box[name]['type']), sub=str(self._box[name]['sub']))

    def on_navigation_btn_group_clicked(self, *arg):
        index = self.navigation_btn_group.checkedId()
        self.stacked_widget.setCurrentIndex(index)
    
    def on_sel_num_slider_value_changed(self, value):
        self.file_list_widget.selectionModel().clear()
        for i in range(value):
            item = self.file_list_widget.item(i)
            item.setSelected(1)
        
    def on_file_list_widget_selection_changed(self):
        sel_items = self.file_list_widget.selectedItems()
        self.sel_num_line.setText(str(len(sel_items)))
        self.submit_btn.updateCustomText(str(len(sel_items)))
        
    def get_maya_file(self, root_path):
        maya_file = []
        if os.path.isdir(root_path):
            maya_file = [f for f in os.listdir(root_path) if f.endswith('.mb')]
        return maya_file
        
    def add_file_list_widget_item(self):
        self.file_list_widget.clear()
        root_path = self.root_line.text()
        if not os.path.isdir(root_path):
            return
        maya_file = self.get_maya_file(root_path)
        if maya_file:
            if self.manager:
                assign_data = self.manager.assignData
                if assign_data:
                    result_data = [f for f in maya_file if f not in assign_data]
                else:
                    result_data = maya_file
                if result_data:
                    result_data.sort()
                    self.file_list_widget.addItems(result_data)
                    self.sel_num_slider.setMinimum(0)
                    self.sel_num_slider.setMaximum(len(result_data))
                    self.sel_num_slider.setEnabled(1)
                    self.submit_btn.setEnabled(1)
                    return

        self.sel_num_slider.setEnabled(0)
        self.submit_btn.setEnabled(0)

    def on_root_btn_clicked(self):
        his_path = self.root_line.text()
        if not os.path.isdir(his_path):
            # his_path = 'C:/Users/%s/Desktop' % getpass.getuser()
            # his_path = 'D:/work/test/temp/ep005'
            his_path = 'H:/project_baosuheti_171128/009_animation/temp'
        file_dialog = QtGui.QFileDialog(self, directory=his_path)
        root_path = file_dialog.getExistingDirectory()
        if root_path:
            root_path = root_path.replace('\\', '/')
            self.update_server_task(root_path)
            if self.get_maya_file(root_path):
                if not self.myThread.state:
                    self.myThread.start()

                self.submit_data_frame.setEnabled(1)
                self.root_line.setText(str(root_path))
                if root_path in self._manager_data:
                    return
                self._manager_data.append(root_path)
                for box_uuid, type_data in self._box.iteritems():
                    # self._box[box_uuid] = dict(box=box, type=name, sub='all')
                    manager = BatchManager(type_data['type'], root_path, type_data['sub'])
                    self.scan_data(manager, type_data)
                return
        self.submit_data_frame.setEnabled(0)
        
    def scan_data(self, manager, type_data):
        taskErrorData = manager.taskErrorData
        taskOkData = manager.taskOkData
        taskAssignData = manager.taskAssignData
        result = {}
        data = []
        if taskErrorData:
            for _error in taskErrorData.keys():
                result[_error] = dict(status='Ok', image=":icons/failure.png")
            data.extend(taskErrorData.keys())
        if taskOkData:
            for _ok in taskOkData.keys():
                result[_ok] = dict(status='Ok', image=":icons/success.png")
            data.extend(taskOkData.keys())
        if taskAssignData:
            result_data = [f for f in taskAssignData if f not in data]
            if result_data:
                for _assign in result_data:
                    result[_assign] = dict(status='Waiting', image=":icons/clock.png")
        if result:
            file_list = result.keys()
            file_list.sort()
            for file_name in file_list:
                self._add_task_view_item(manager, type_data, file_name, result[file_name]['status'], result[file_name]['image'])
                
    def on_server_refersh_btn_clicked(self):
        root_path = self.root_line.text()
        if not os.path.isdir(root_path):
            return
        if root_path:
            root_path = root_path.replace('\\', '/')
            self.update_server_task(root_path)
            
    def update_server_task(self, root_path):
        self.server_task_item_model.clear()
        self.server_task_item_model.setHorizontalHeaderItem(0, QtGui.QStandardItem(u"文件名"))
        self.server_task_item_model.setHorizontalHeaderItem(1, QtGui.QStandardItem(u"类型"))
        self.server_task_item_model.setHorizontalHeaderItem(2, QtGui.QStandardItem(u"任务分组"))
        self.server_task_item_model.setHorizontalHeaderItem(3, QtGui.QStandardItem(u"所有者"))
        self.server_task_item_model.setHorizontalHeaderItem(4, QtGui.QStandardItem(u"状态"))
        # for batch_type in self._box.keys():
        for box_uuid, type_data in self._box.iteritems():
            temp_manager = BatchManager(type_data['type'], root_path, type_data['sub'])
            errorData = temp_manager.errorData
            okData = temp_manager.okData
            assignData = temp_manager.assignData
            data = {}
            result = {}
            if errorData:
                for _error in errorData.keys():
                    result[_error] = dict(status='Ok', image=":icons/failure.png", user=errorData[_error]["user"])
                data.update(errorData)
            if okData:
                for _ok in okData.keys():
                    result[_ok] = dict(status='Ok', image=":icons/success.png", user=okData[_ok]["user"])
                data.update(okData)
            if assignData:
                assign_file = list(set(assignData))
                if data:
                    result_data = {f:assignData[f] for f in assign_file if f not in data}
                else:
                    result_data = assignData
                if result_data:
                    for _assign in result_data:
                        result[_assign] = dict(status='Waiting', image=":icons/clock.png", user=result_data[_assign]["user"])
            if result:
                file_list = result.keys()
                file_list.sort()
                for file_name in file_list:
                    self._add_server_table_item(type_data, file_name, result[file_name]['status'],result[file_name]['user'], result[file_name]['image'])
                
    def _add_server_table_item(self, type_data, task,  state, user, image):

            row = self.server_task_item_model.rowCount()
            #self.server_task_item_model.setItem(row, 0, QtGui.QStandardItem(QtGui.QIcon(icon), task))
            # name
            self.server_task_item_model.setItem(row, 0, QtGui.QStandardItem(QtGui.QIcon(image),task))
            self.server_task_item_model.setItem(row, 1, QtGui.QStandardItem(type_data['type']))
            self.server_task_item_model.setItem(row, 2, QtGui.QStandardItem(type_data['sub']))
            self.server_task_item_model.setItem(row, 3, QtGui.QStandardItem(user))
            self.server_task_item_model.setItem(row, 4, QtGui.QStandardItem(state))
            
    def on_submit_btn_clicked(self):
        items = self.file_list_widget.selectedItems()
        task_list = []
        if not items:
            return
        for item in items:
            task_list.append(item.text()) 
        if self.manager.isAssignDataLock:
            message_box = QtGui.QMessageBox().information(self, u'提示', u'其他用户(ID:%s)正在提交中，数据被锁定，请稍后再试！' % self.manager.assignUser)
            return
        self.manager.setAssignDataLock(1)
        assign_data = self.manager.assignData
        if assign_data:
            result_data = [f for f in task_list if f not in assign_data]
        else:
            result_data = task_list
        if result_data:
            self.submit_task(self.get_batch_type(), result_data)
            data = {task:{"user":self.manager.id} for task in result_data}
            self.manager.updateAssignData(data)
            self.manager.updateTaskAssignData(result_data)
        self.manager.setAssignDataLock(0)
        self._refresh()

        
    def submit_task(self, type_data, task_data):
        taskAssignData = self.manager.taskAssignData
        if taskAssignData:
            result_data = [f for f in task_data if f not in taskAssignData]
            self.add_task_view_item(self.manager, type_data, result_data, 'Waiting', ":icons/clock.png")
        else:
            self.add_task_view_item(self.manager, type_data, task_data, 'Waiting', ":icons/clock.png")
            
    def add_task_view_item(self, manager, type_data, task_data, state, image):
        if not task_data:
            return
        if isinstance(task_data, list):
            task_data.sort()
            for task in task_data:
                self._add_task_view_item(manager, type_data, task, state, image)
        elif isinstance(task_data, str):
            self._add_task_view_item(manager, type_data, task, state, image)
            
    def _add_task_view_item(self, manager, type_data, task, state, image):
        row = self.task_item_model.rowCount()
        #self.task_item_model.setItem(row, 0, QtGui.QStandardItem(QtGui.QIcon(icon), task))
        # name
        self.task_item_model.setItem(row, 0, QtGui.QStandardItem(QtGui.QIcon(image),task))
        self.task_item_model.setItem(row, 1, QtGui.QStandardItem(type_data['type']))
        # self.task_item_model.setItem(row, 2, QtGui.QStandardItem(manager.id))
        self.task_item_model.setItem(row, 2, QtGui.QStandardItem(type_data['sub']))
        self.task_item_model.setItem(row, 3, QtGui.QStandardItem(manager.id))
        self.task_item_model.setItem(row, 4, QtGui.QStandardItem(state))
        if state == 'Waiting':
            cmd_str = self.get_cmd(manager, type_data, task)
            item = self.task_item_model.item(row)
            # print cmd_str
            self.myThread.task_data.append({'cmd':cmd_str, "itemModel":self.task_item_model, 'item':item, 'manager':manager, 'file':task, 'type_data': type_data})

    def get_cmd(self, manager, type_data, task_name):
        data = self._data[type_data['type']]
        engine = data['engine']
        if type_data['sub'] != 'all':
            script = data['sub'][type_data['sub']]['script']
        else:
            script = data['script']
        cmd_format = '{engine} -file "{file}" -script "{script}"'

        hooks_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'hooks', script).replace('\\', '/')
        file_path = os.path.join(manager.rootPath, task_name).replace('\\', '/')
        return cmd_format.format(engine=engine, file=file_path, script=hooks_path)
        
    def showEvent(self, event):
        super(BatchManagerUi, self).showEvent(event)
        if self._init_data():
            self._ui()
        
        
if __name__ == "__main__":
    app = QtGui.QApplication([])
    bmui = BatchManagerUi()
    bmui.show()
    app.exec_()
        